package flex.cc.vehicle_svr.service.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.base.exception.BusinessException;
import flex.cc.basicinformation.entity.ChannelDataEntity;
import flex.cc.basicinformation.service.ChannelService;
import flex.cc.common.utils.CommonUtils;
import flex.cc.common.utils.DateUtil;
import flex.cc.common.utils.HttpClientUtil;
import flex.cc.core.utils.RequestUtil;
import flex.cc.order.manage.dao.OrderTrackDao;
import flex.cc.order.manage.dto.order.OrderImgEntity;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.service.OrderImgService;
import flex.cc.order.manage.service.OrderMainService;
import flex.cc.util.EncryptionDecryption;

/**
 * 
 * @author WANGCONG
 * 2021年9月13日下午1:42:39
 * @desc 服务单图像回传上游
 */
@Service
public class UpPushService {
	
	/** 回传图片接口参数 */
	public static final String CHANNEL = "ZXHY";
	/** 回传图片接口参数 */
	public static final String KEY = "CSHAPPZX";
	
	@Resource
	private OrderImgService orderImgService;
	@Resource
	private OrderMainService orderMainService;
	@Resource
    private OrderTrackDao orderTrackDao;
	@Resource
	private ChannelService channelService;
	
	//SIT
//	private static String prefix = "http://http://82.157.24.156:9002/file/pictures"; //图片路径前缀
//	private static String synImg_url = "https://uatcarlife.ygbx.com:9443/suncar-card/thirdApi/syncPhotoInfo";
//	private static String status_url = "http://1.202.235.87:9001/CCHttpServiceINT/servlet/rescueOperationOptional";
	//UAT
//	private static String prefix = "http://82.157.33.136:9002/file/pictures"; //图片路径前缀
//	private static String synImg_url = "https://carlife.ygbx.com/suncar-card/thirdApi/syncPhotoInfo";
//	private static String status_url = "http://95510.sinosig.com:9001/CCHttpService/servlet/rescueOperationOptional";
	
	@Value("${pengda.prefix}")
    private String prefix;
	@Value("${pengda.synImg}")
	private String synImg_url;
	@Value("${pengda.synStatus}")
	private String status_url;
	
	/**
   	*
   	* @author WANGCONG
   	* 2022年2月25日下午15:16:29
   	* @desc 救援单手工图片回传
   	*/
	public Map<String,Object> artificialPushImg(String orderNo, String sourceName) {
		Map<String,Object> result = new HashMap<String,Object>();
		Map<String, Object> order_param = new HashMap<String,Object>();
		order_param.put("orderNo", orderNo);
		try {
			if("00".equals(sourceName)){
				result.put("responseCode", "01");
				result.put("responseMsg", orderNo+"是自营渠道服务单，不用进行回传");
			}else{
				List<OrderImgEntity> imgList = orderImgService.queryImgByOrderNo(orderNo);
				if(imgList==null || imgList.size()==0){
					result.put("responseCode", "01");
					result.put("responseMsg", orderNo+"没有图片，不能进行回传");
				}else{
					//业务处理
					Map<String, String> channelMap = new HashMap<String, String>();
					channelMap.put("clientId", sourceName);
					channelMap.put("urlType", "5"); //图片回传
					ChannelDataEntity channelData = channelService.findChannelDataByParam(channelMap);
					if(PublicUtil.isEmpty(channelData)){
						result.put("responseCode", "01");
						result.put("responseMsg", "未配置上游回传图片接口地址，不能进行回传操作");
					}else{
						synImg_url = channelData.getUrl();
						OrderMainEntity orderMain = orderMainService.getOneByParams(order_param);
						String status = orderMain.getStatus();
						String ownerOrderNo = orderMain.getOwnerOrderNo();
						List<String> picUrls = new ArrayList<String>();
						for(int j=0; j<imgList.size(); j++){
							String url = imgList.get(j).getUrl();
							String localUrl = imgList.get(j).getLocalUrl();
							if(PublicUtil.isNotEmpty(localUrl)){
								picUrls.add(prefix + localUrl);
							}else{
								picUrls.add(url);
							}
						}
						Map<String, Object> params = new HashMap<>();
						params.put("customerCode",ownerOrderNo);
						params.put("caseNo",ownerOrderNo);
						params.put("carServiceType","0");
						params.put("tracktype","");
						params.put("picList", picUrls);
						String cshToken = DESEncrypt(params.get("customerCode") + "_" + System.currentTimeMillis() + "_" + CHANNEL, KEY);
						AtomicReference<Integer> counter = new AtomicReference<Integer>(0);
						String temp_code = ""; //记录接口回写的code码，便于轨迹备注插入
						while(counter.get()<3){
							//{"resCode":"SUCCESS","resMsg":"成功"}；
							String response = HttpClientUtil.sendHttpPost(synImg_url, JSONObject.toJSONString(params), new HashMap<String, String>(){{
								put("Content-Type", "application/json;charset=utf-8");
								put("cshToken", cshToken);
								put("channel", CHANNEL);
					        }});
							if (response != null) {
			            		try {
			            			JSONObject resultObj = JSONObject.parseObject(response);
			                        String resCode = PublicUtil.isNotEmpty(resultObj.get("resCode")) ? resultObj.get("resCode").toString() : null; 
			                        temp_code = resCode;
			                        if(PublicUtil.isNotEmpty(resCode) && !"SUCCESS".equals(resCode)){
			                        	counter.compareAndSet(counter.get(), counter.get()+1);
			                        }else{
			                        	counter.getAndSet(5);
			                        }
								} catch (Exception e) {
									counter.getAndSet(5);
								}
			            	}else {
			            		counter.compareAndSet(counter.get(), counter.get()+1);
			            	}
						}
						if("SUCCESS".equals(temp_code)){//成功
							result.put("responseCode", "00");
							result.put("responseMsg", orderNo+"救援单图片回传成功");
			            	saveTrack(orderNo, "07", "手动执行图片回传成功", status, new Date(), RequestUtil.getLoginUser());
						}else{
							result.put("responseCode", "01");
							result.put("responseMsg", orderNo+"救援单图片回传失败");
							saveTrack(orderNo, "07", "手动执行图片回传失败", status, new Date(), RequestUtil.getLoginUser());
						}
					}
				}
			}
		} catch (Exception e) {
			result.put("responseCode", "01");
			result.put("responseMsg", "后台处理异常");
		}
		return result;
	}
	
	private void saveTrack(String orderNo, String trackType, String trackDesc, String status, Date currentDate, LoginAuthDto loginUser){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(loginUser.getUserCode());
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(loginUser.getUserCode());
        orderTrackDao.insert(orderTrackEntity);
    }
	
	/**
	 * 
	 * @author WANGCONG
	 * 2021年9月13日下午1:43:52
	 * @param picUrls 
	 * @desc 图像回传上游
	 */
    public void pushImg(String orderNos) throws Exception {
		String[] orderNoArr = orderNos.split(",");
		String filePath = "/apps/appwork/pushInfo/pushImg/"+DateUtil.getyyMMddDate()+".csv";
		for(int i=0; i<orderNoArr.length; i++){
			String orderNo = orderNoArr[i];
			List<OrderImgEntity> imgList = orderImgService.queryImgByOrderNo(orderNo);
			if(imgList.size()>0){
				Map<String, Object> order_param = new HashMap<>();
				order_param.put("orderNo", orderNo);
				OrderMainEntity orderMain = orderMainService.getOneByParams(order_param);
				if(orderMain!=null){
					String sourceName = orderMain.getSourceName();
					if("00".equals(sourceName)){
						writeCsv(orderNo+"-执行结果=自营不回传", filePath);
					}else{
						String ownerOrderNo = orderMain.getOwnerOrderNo();
						List<String> picUrls = new ArrayList<String>();
						for(int j=0; j<imgList.size(); j++){
							String url = imgList.get(j).getUrl();
							String localUrl = imgList.get(j).getLocalUrl();
							if(PublicUtil.isNotEmpty(localUrl)){
								picUrls.add(prefix + localUrl);
							}else{
								picUrls.add(url);
							}
						}
						if(picUrls.size()>0){
							Map<String, Object> params = new HashMap<>();
							params.put("customerCode",ownerOrderNo);
							params.put("caseNo",ownerOrderNo);
							params.put("carServiceType","0");
							params.put("tracktype","");
							params.put("picList", picUrls);
							String cshToken = DESEncrypt(params.get("customerCode") + "_" + System.currentTimeMillis() + "_" + CHANNEL, KEY);
							String result = HttpClientUtil.sendHttpPost(synImg_url, JSONObject.toJSONString(params), new HashMap<String, String>(){{
								put("Content-Type", "application/json;charset=utf-8");
								put("cshToken", cshToken);
								put("channel", CHANNEL);
					        }});
							writeCsv(orderNo+"-执行结果="+result+"，上传报文="+params, filePath);
						}else{
							writeCsv(orderNo+"-执行结果=图片地址为空", filePath);
						}
					}
				}else{
					writeCsv(orderNo+"-执行结果=单号不存在", filePath);
				}
			}else{
				writeCsv(orderNo+"-执行结果=图片为空", filePath);
			}
		}
		
    }

	public static void writeCsv(String str, String filePath) {
		File outfile = new File(filePath);// 存储到新文件的路径
		try {
			if (outfile.exists()) {
				String content = readCSV(filePath);
				content += str + "\t\n";
				BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
				bw.write(content);
				bw.close();
			} else {
				BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
				bw.write(str);
				bw.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    
	//按照文件中字符串原格式 读取文件
	public static String readCSV(String filePath) {
		try {
			InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "UTF8");
			BufferedReader reader = new BufferedReader(isr);
			String line = "";
			String content = "";
			while ((line = reader.readLine()) != null) {
				content += line + "\t\n";
			}
			reader.close();
			isr.close();
			return content;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * DES 加密
	 * */
	public static String DESEncrypt(String content, String key){
		try{
			Cipher cipher = Cipher.getInstance( "DES/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "DES"), 
					new IvParameterSpec(new byte[]{1,2,3,4,5,6,7,8}));
	        return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes("UTF8")));
		}catch(Exception e){
			throw new BusinessException("加密错误");
		}
	}

	public void pushStatus(String orderNos) throws Exception {
		String[] orderNoArr = orderNos.split(",");
		String filePath = "/apps/appwork/pushInfo/pushStatus/"+DateUtil.getyyMMddDate()+".csv";
		for(int i=0; i<orderNoArr.length; i++){
			String orderNo = orderNoArr[i];
			Map<String, Object> order_param = new HashMap<>();
			order_param.put("orderNo", orderNo);
			OrderMainEntity orderMain = orderMainService.getOneByParams(order_param);
			if(orderMain==null){
				writeCsv(orderNo+"-执行结果：单号不存在", filePath);
			}else{
				String orderStatus = orderMain.getStatus();
				String status = caseStatus(orderStatus);
				if(StringUtils.isEmpty(status)){
					writeCsv(orderNo+"-执行结果：当前单号状态为"+orderStatus+"，无需回传", filePath);
				}else{
					Map<String, Object> body = new HashMap<String, Object>();
					Map<String, String> requestHeader = new HashMap<String, String>();
					Map<String, String> requestBody = new HashMap<String, String>();
					requestHeader.put("partnerCode", CommonUtils.PARTNERCODE);
					requestHeader.put("clientId", CommonUtils.CLIENTID);
					requestHeader.put("requestCode", "modifyStatus");
					body.put("requestHeader", requestHeader);
					
					requestBody.put("ownerOrderNo", orderMain.getOwnerOrderNo());
					requestBody.put("salvationStatus", status);
					requestBody.put("serviceAmount", "0");
					requestBody.put("serviceContent", "");  //服务商备注
					requestBody.put("cancelTime", "");  //取消时间
					requestBody.put("cancelReason", "");//服务商取消原因，07师傅报备取消时有值
					requestBody.put("statusTime", ""); //状态改变时间
					body.put("requestBody", requestBody);
					
					try {
						EncryptionDecryption des = new EncryptionDecryption();
						String jsonStr = JSON.toJSONString(body);
						System.out.println("加密前的回传报文=" + jsonStr);
						String jsonBody = des.encrypt(jsonStr);
						System.out.println("加密后的回传报文=" + jsonBody);
						String result = HttpClientUtil.sendHttpPost(status_url, jsonBody, null);
						System.out.println("渠道商返回响应加密报文=" + result);
						if(result == null || "".equals(result)){
							writeCsv(orderNo+"-执行结果：状态回写接口响应报文为空，上传报文="+jsonStr, filePath);
						}else{
							result = des.decrypt(result.trim(), "UTF-8");
							writeCsv(orderNo+"-执行结果="+result+"，上传报文="+jsonStr, filePath);
							System.out.println("渠道商返回响应报文解密=" + result);
							JSONObject json = JSONObject.parseObject(result);
						}
					}catch (Exception e) {
						writeCsv(orderNo+"-解析报错", filePath);
					}
				}
			}	
		}
		
	}

	public String caseStatus(String status) {
		String result = "";
		switch (status) {
			case "01":
				result = "";
				break;
			case "02":
				result = "DISTRIBUTED";//供应商已受理
				break;
			case "03":
				result = "STARTED_DISPATCH";//坐席已派单
				break;
			case "04":
				result = "DISPATCHED";//已接单
				break;
			case "05":
				result = "";//开始出发
				break;
			case "06":
				result = "ARRIVED";//到达现场
				break;
			case "07":
				result = "ARRIVED";
				break;
			case "08":
				result = "COMPLETE";//服务完成
				break;
			case "09":
				result = "";
				break;
			case "10": //取消有费用
				result = "CANCEL_COST";
				break;
			case "11": //取消无费用
				result = "";
				break;
			default:
				break;
		}
		return result;
	}
	
}
